<html>
	<head>
		<title>Learning WebGL</title>
		<script id="shader-fs" type="x-shader/x-fragment">
			void main(void) {
				gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
			}
		</script>

		<script id="shader-vs" type="x-shader/x-vertex">
			attribute vec3 position;

			uniform mat4 mvpMatrix;

			void main(void) {
				gl_Position = mvpMatrix * vec4(position, 1.0);
			}
		</script>
	</head>

	<body>
		<div id='container'></div>
		<script type='text/javascript' src='noogl.js'></script>
		<script>
			(function () {
				function Mesh(webgl) {
		var vertices = [];
		var faces = [];
		return {
			createFace: function (options) {
							var f = {
								options: options,
								vertices: [],
								addVertex : function (v) {
												this.vertices.push(vertices.length);
												vertices.push(v);
											}
							};
							faces.push( f );
							return f;
					 }

		};
	}

	function ShaderProgram(webgl, shaders) {
		var program = webgl.createProgram();
		for (var i = 0, l = shaders.length; i < l; i++) {
			shaders[i].attachTo(program);
		}

		webgl.linkProgram(program);

		if (!webgl.getProgramParameter(program, webgl.LINK_STATUS)) {
			throw new Error('GLSL linker\n' + webgl.getProgramInfoLog(program));
		}

		return {
			use: function() {
					 webgl.useProgram(program);

				 }
		};
	}

	function Shader(webgl, script_id) {
		var script = document.getElementById(script_id);
		if (!script) throw new Error(script_id + ': shader <script> tag not found');

		var shader;
		if (script.type === 'x-shader/x-fragment') {
			shader = webgl.createShader(webgl.FRAGMENT_SHADER);
		} else if (script.type === 'x-shader/x-vertex') {
			shader = webgl.createShader(webgl.VERTEX_SHADER);
		} else {
			throw new Error(script_id + ': unknown shader type: ' + script.type);
		}

		webgl.shaderSource(shader, script.innerText);
		webgl.compileShader(shader);

		if (!webgl.getShaderParameter(shader, webgl.COMPILE_STATUS)) {
			throw new Error(script_id + ': GLSL compiler\n' + webgl.getShaderInfoLog(shader));
		}

		return {
			attachTo : function (program) {
						   webgl.attachShader(program, shader);
					   }
		};
	}

	function Canvas(options) {
		var container = options['container'] || document.body;

		var canvas = document.createElement('canvas');
		canvas.width = options['width'] || 400;
		canvas.height = options['height'] || 300;

		var webgl = canvas.getContext('webgl');
		if (!webgl) throw new Error('could not get webgl context');

		return {
			appendTo : function(container) {
						   container.appendChild(canvas);
					   },
					 createProgram : function(shaders) {
										 return new ShaderProgram(webgl, shaders);
									 },
					 createShader: function(script_id) {
									   return new Shader(webgl, script_id);
								   },
					 createMesh: function() {
									 return new Mesh(webgl);
								 }
		};
	}
				var gl = new Canvas({
					width: 640,
					height: 480,
					clearColor: { r: 0, g: 0, b: 0, a: 1 } });
				//			 gl.appendTo(document.body);
				//			 gl.appendTo(document.getElementById('container'));
				/*
				gl.autoResize();
				window.addEventListener(onresize, function() {
					gl.resize({width:, height:document.body.clientHeight()});
				});
				*/

				var program = gl.createProgram([
				gl.createShader('shader-vs'),
				gl.GlslShader('shader-fs') ]);
				program.use();

				/*

				function Mesh.render() {
					if (!isBaked()) {
						// send array buffer data
					}
					// drawElements
				}
				*/

				var mesh = gl.createMesh();
				var triangle = mesh.createFace({color:[1,0,0,1]});
				triangle.addVertex({position:[0,1,-5]});
				triangle.addVertex({position:[-1,-1,-5]});
				triangle.addVertex({position:[-1,1,-5]});

				mesh.bake(); // enable static draw.
				//			mesh.translate( ); // manipulate Model Matrix
				//			mesh.rotate( ); // manipulate Model Matrix

				/*
				mesh.faces();
				mesh.faceVertices(face);

				var scene = gl.createScene();
				scene.add(triangle);

				// PerspectiveCamera defines Projection Matrix
				// camera.{position, lookat, up} define View Matrix
				// these are affected by camera.rotate, camera.translate
				var camera = gl.createPerspectiveCamera({
					fovydeg: 45,
					aspect: 5 / 4,
					near: .1,
					far: 100,
					position: [0, 0, 0],
					lookat: [0, 0, -1],
					up: [0, 1, 0]});

				camera.rotate(new Quaternion({degs:1, u: camera.up, origin: mesh.centerOfMass()}) );
				// camera.rotate(new Quaternion({rads:Math.PI/180, u: camera.up, origin: mesh.centerOfMass()}) );

				camera.render(scene);
				//			scene.render(camera);
				*/
			}());
		</script>
	</body>
</html>

